﻿using NPOI.SS.Formula;
using NPOI.SS.Formula.Functions;
using NPOI.SS.UserModel;
using NPOI.XSSF.Streaming.Values;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace ExcelHelperSpace
{
    public class TypeObject : ITypeObjectFactory
    {
        /// <summary>
        /// 创建typeobject
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <param name="dic"></param>
        /// <returns></returns>
        public object Create(Type t, Dictionary<string, object> dic)
        {
            //实例化对象
            var obj = t.Assembly.CreateInstance(t.FullName);

            ////对象赋值
            //var pointDic = new Dictionary<string, Properte>();
            //foreach (var prop in t.GetProperties())
            //{
            //    var objs = prop.GetCustomAttributes(typeof(SlwDes), true);
            //    var Des = prop.Name;
            //    if (objs.Length > 0 && ((SlwDes)objs[0]).Des != null)
            //    {
            //        //有列字段描述
            //        Des = ((SlwDes)objs[0]).Des;
            //        pointDic.Add(Des, new Properte { Name = prop.Name, SystemName = prop.PropertyType.Name });
            //    }

            //    //获取对应的赋值对象
            //    if (dic.ContainsKey(Des))
            //    {
            //        var sValue = dic[Des];
            //        //开始赋值
            //        prop.SetValue(obj, sValue);
            //    }
            //}

            return obj;
        }

        /// <summary>
        /// 创建typeobject
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <param name="cell">excel 表的列信息</param>
        /// <param name="firstdic">列表和字段</param>
        /// <returns></returns>
        public object Create(Type t, IEnumerable<ICell> cell, Dictionary<string, int> firstdic)
        {
            //实例化对象
            var obj = t.Assembly.CreateInstance(t.FullName);

            if (cell.Count() == 0)
            {
                return new object();
            }

            //对象赋值
            foreach (var prop in t.GetProperties())
            {
                var objs = prop.GetCustomAttributes(typeof(SlwDes), true);
                var Des = prop.Name;
                if (objs.Length > 0 && ((SlwDes)objs[0]).Des != null)
                {
                    //有列字段描述
                    Des = ((SlwDes)objs[0]).Des;
                }

                //判断是否存在此key
                if (firstdic.ContainsKey(Des))
                {
                    //进行字段赋值
                    var columnIndexCell = cell.Where(e => e.ColumnIndex == firstdic[Des]).FirstOrDefault();
                    if (columnIndexCell != null)
                    {
                        if (columnIndexCell.CellType == CellType.String)
                        {
                            var sValue = columnIndexCell.StringCellValue;

                            if (prop.PropertyType.Name == "String")
                            {
                                prop.SetValue(obj, sValue != null ? sValue : "");
                            }
                            else 
                            {
                                prop.SetValue(obj, sValue != null ? sValue.ToString() : "");
                            }
                            continue;
                        }
                        if (columnIndexCell.CellType == CellType.Numeric)
                        {
                            var sValue = columnIndexCell.NumericCellValue;

                            if (prop.PropertyType.Name == "Int16")
                            {
                                prop.SetValue(obj, sValue != null ? Convert.ToInt16(sValue) : "");
                            }
                            else if (prop.PropertyType.Name == "Int32")
                            {
                                prop.SetValue(obj, sValue != null ? Convert.ToInt32(sValue) : "");
                            }
                            else if (prop.PropertyType.Name == "Int64")
                            {
                                prop.SetValue(obj, sValue != null ? Convert.ToInt64(sValue) : "");
                            }
                            else if (prop.PropertyType.Name == "Double")
                            {
                                prop.SetValue(obj, sValue != null ? Convert.ToDouble(sValue) : "");
                            }
                            else if (prop.PropertyType.Name == "Double")
                            {
                                prop.SetValue(obj, sValue != null ? Convert.ToDouble(sValue) : "");
                            }
                            else
                            {
                                prop.SetValue(obj,0);
                            }
                            break;
                        }
                        if (columnIndexCell.CellType == CellType.Unknown)
                        {
                            continue;
                        }
                        if (columnIndexCell.CellType == CellType.Boolean)
                        {
                            var sValue = columnIndexCell.BooleanCellValue;
                            if (prop.PropertyType.Name == "Boolean")
                            {
                                prop.SetValue(obj, sValue);
                            }
                            continue;
                        }
                        if (columnIndexCell.CellType == CellType.Formula)
                        {
                            continue;
                        }
                        if (columnIndexCell.CellType == CellType.Blank)
                        {
                            continue;
                        }
                        if (columnIndexCell.CellType == CellType.Error)
                        {
                            continue;
                        }
                    }
                }
                else
                {
                    continue;
                }
            }

            return obj;
        }




    }

}
